package com.linkoog.devtools.json.toolwindow.ui.jsontree;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.linkoog.devtools.utils.JacksonUtil;
import com.linkoog.devtools.utils.StringUtils;

import java.util.Iterator;
import java.util.Map;

public class JsonTreeUtils {


    public static JsonTreeNode buildJsonTree(String json){
        JsonTreeNode root = new JsonTreeNode("<root>", new TextNode(""));
        if (StringUtils.isBlank(json)){
            return root;
        }

        try {
            JsonNode node = JacksonUtil.readTree(json);
            buildJsonTree(root, node);
        } catch (Exception ignore){
        }
        return root;
    }

    public static void buildJsonTree(JsonTreeNode root, JsonNode node){
        if (node.isValueNode()) {
            JsonTreeNode childNode = new JsonTreeNode(node.toString(), new TextNode(""));
            root.add(childNode);
            return;
        }

        if (node.isObject()) {
            Iterator<Map.Entry<String, JsonNode>> it = node.fields();
            while (it.hasNext()) {
                Map.Entry<String, JsonNode> entry = it.next();
                String key = entry.getKey();
                JsonNode value = entry.getValue();

                JsonTreeNode childNode = new JsonTreeNode(key, value);
                root.add(childNode);
                if (! value.isValueNode()) {
                    buildJsonTree(childNode, value);
                }
            }
            return;
        }

        if (node.isArray()) {
            Iterator<JsonNode> it = node.iterator();
            int i = 0;
            while (it.hasNext()) {
                String key = "[" + i +"]";
                JsonNode value = it.next();
                JsonTreeNode childNode = new JsonTreeNode(key, value);
                root.add(childNode);

                if (!value.isValueNode()) {
                    buildJsonTree(childNode, value);
                }
                i++;
            }
            return;
        }
    }

}
